#include <stdio.h>
#include <unistd.h>
#include "mpi.h"

void add(void * invec, void * inoutvec, int * len,
		MPI_Datatype *datatype)
{
	int i = 0;
	if( *datatype == MPI_INT )
	{
		int * int_in = (int *)invec;
		int * int_inout = (int *)inoutvec;

		for( i = 0; i < *len; i++ )
		{
			int_inout[i] += int_in[i];
		}
	}
}

int
main(int argc, char **argv)
{
	int size, rank;
	int solution = 0;
	MPI_Op operation;

	int sendbuf, i;
	int recvbuf = 0;
	
	MPI_Init(&argc, &argv);
	
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);

	sendbuf = rank;
	
	if( size < 2 )
	{
		printf("Please run this program with more than one process.\n");
		exit(1);
	}

	for( i = 0; i < size; i++ )
	{
		solution += i;
	}
	
	printf("Size %d, Rank %d\n",size,rank);

	MPI_Op_create(&add,0,&operation);
	MPI_Reduce(&sendbuf,&recvbuf,1,MPI_INT,operation,0,MPI_COMM_WORLD);

	if( rank == 0 )
	{
		printf("Solution should be %d. Solution was actually %d.\n",
				solution,recvbuf);
		
		if( recvbuf == solution )
		{
			printf("Success\n");
		}
		else
		{
			printf("Failure\n");
		}
	}

	MPI_Finalize();
	
	return 0;
}

